package com.liuanbang.saro.sarodemo.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.liuanbang.saro.sarodemo.R;
import com.liuanbang.saro.sarodemo.util.DensityUtils;

/**
 * Created by 刘安邦 on 2017/3/1.
 * Email:liuanbang@aliyun.com
 * 描述:学习网址:http://blog.csdn.net/qq_31715429/article/details/53894623 2017/3/1
 * 修改:
 */
public class CirclePercentView extends View {
    private int mCircleColor;
    private int mArcColor;
    private int mArcWidth;
    private int mPercentTextColor;
    private int mPercentTextSize;
    private int mRadius;
    private float mCurPercent = 0.0f;

    private Paint mCirclePaint;
    private Paint mArcPaint;
    private Paint mPercentTextPaint;
    private Rect mTextBound;
    private RectF mArcRectF;

    private OnClickListener mOnClickListener;

    /**
     * 5.暴露一个动态设置百分比的方法
     */
    public void setCurPercent(float curPercent) {
        ValueAnimator anim = ValueAnimator.ofFloat(mCurPercent, curPercent);
        //动画时长 由百分比大小决定
        //Math.abs()取绝对值
        anim.setDuration((long) (Math.abs(mCurPercent - curPercent) * 20));

        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            //动画中每一帧更新时调用
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                mCurPercent = (float) (Math.round(value * 10)) / 10;//四舍五入保留到小数点后两位
                invalidate();//重绘，重走onDraw()方法，这也是不能再onDraw()中创建对象的原因
            }
        });

        anim.start();
    }

    public void setOnCircleClickListener(OnClickListener onClickListener) {
        this.mOnClickListener = onClickListener;
    }

    public CirclePercentView(Context context) {
        this(context, null);
    }

    public CirclePercentView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CirclePercentView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //1.获取自定义属性值
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CirclePercentView, defStyleAttr, 0);
        mCircleColor = ta.getColor(R.styleable.CirclePercentView_circleBg, 0xff8e29fa);
        mArcColor = ta.getColor(R.styleable.CirclePercentView_arcColor, 0xffffee00);
        mPercentTextColor = ta.getColor(R.styleable.CirclePercentView_percentTextColor, 0xffffee00);
        mArcWidth = ta.getDimensionPixelSize(R.styleable.CirclePercentView_arcWidth, DensityUtils.dp2px(context, 16));
        mPercentTextSize = ta.getDimensionPixelSize(R.styleable.CirclePercentView_percentTextSize, DensityUtils.sp2px(context, 16));
        mRadius = ta.getDimensionPixelSize(R.styleable.CirclePercentView_radius, DensityUtils.dp2px(context, 100));
        //及时回收资源
        ta.recycle();

        //2.创建画图所需要的对象
        //反锯齿
        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //
        mCirclePaint.setStyle(Paint.Style.FILL);
        //
        mCirclePaint.setColor(mCircleColor);

        mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mArcPaint.setStyle(Paint.Style.STROKE);
        mArcPaint.setStrokeWidth(mArcWidth);
        mArcPaint.setColor(mArcColor);
        mArcPaint.setStrokeCap(Paint.Cap.ROUND);//使圆弧两头圆润

        mPercentTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPercentTextPaint.setStyle(Paint.Style.STROKE);
        mPercentTextPaint.setColor(mPercentTextColor);
        mPercentTextPaint.setTextSize(mPercentTextSize);


        mArcRectF = new RectF();//圆弧外接矩形

        mTextBound = new Rect();//文本的范围矩形

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnClickListener != null) {
                    mOnClickListener.onClick(CirclePercentView.this);
                }
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureDimension(widthMeasureSpec), measureDimension(heightMeasureSpec));
    }

    private int measureDimension(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = 2 * mRadius;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    /**
     * 4.重写OnDraw()方法,绘制圆,圆弧和百分比文本,注意坐标计算
     */
    @Override
    protected void onDraw(Canvas canvas) {

        //画圆
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mCirclePaint);

        /**
         * Rect类主要用于表示坐标系中的一块矩形区域，并可以对其做一些简单操作。这块矩形区域，需要用左上右下两个坐标点表示（left,top,right,bottom）,你也可以获取一个Rect实例的Width和Height。
         . 联系：
         都是用于表示坐标系中的一块矩形区域，并可以对其做一些简单操作。这块矩形区域，需要用左上和右下两个坐标点表示。
         2. 区别：
         (1).精度不一样。Rect是使用int类型作为数值，RectF是使用float类型作为数值。
         (2).两个类型提供的方法也不是完全一致。
         */
        //画圆弧(这里设置4个坐标left X  ,top Y,right X ,bottom Y)
        //首先设置画笔
        mArcRectF.set(getWidth() / 2 - mRadius + mArcWidth / 2, getHeight() / 2 - mRadius + mArcWidth / 2,
                getWidth() / 2 + mRadius - mArcWidth / 2, getHeight() / 2 + mRadius - mArcWidth / 2);
        //(ArcRectF,开始度数,扫过度数,画整个圆还是只画个圆弧,画笔)
        canvas.drawArc(mArcRectF, 270, 360 * mCurPercent / 100, false, mArcPaint);

        String text = mCurPercent + "%";
        //计算文本的宽高
        mPercentTextPaint.getTextBounds(text, 0, String.valueOf(text).length(), mTextBound);
        //画百分比文本(他是从右下角开始画的...这点需要仔细研究上链接的图  )
        canvas.drawText(text, getWidth() / 2 - mTextBound.width() / 2, getHeight() / 2 + mTextBound.height() / 2, mPercentTextPaint);
    }
}